package cn.piggy.gateway.core.datasource.connection;

import cn.piggy.gateway.core.common.CommonUtil;
import cn.piggy.gateway.core.http.HttpStatement;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ConsumerConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.utils.ReferenceConfigCache;
import org.apache.dubbo.rpc.service.GenericService;
import java.util.Map;


public class DubboConnection implements Connection {

    private final GenericService genericService;

    public DubboConnection(ApplicationConfig applicationConfig, RegistryConfig registryConfig,
                           ReferenceConfig<GenericService> reference) {
        // 连接远程服务
        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
        ConsumerConfig consumer = new ConsumerConfig();
        consumer.setRetries(CommonUtil.retries);
        consumer.setLoadbalance(CommonUtil.strategy);
        bootstrap.consumer(consumer).application(applicationConfig)
                .registry(registryConfig).reference(reference).start();
        // 获取泛化接口
        ReferenceConfigCache cache = ReferenceConfigCache.getCache();
        genericService = cache.get(reference);
    }

    /**
     * Dubbo 泛化调用：https://dubbo.apache.org/zh/docsv2.7.5/user/examples/generic-reference/
     */
    @Override
    public Object execute(HttpStatement httpStatement, Map<String, Object> params) throws Exception {
        String methodName = httpStatement.getMethodName();
        String parameterType = httpStatement.getParameterType();
        String parameterName = httpStatement.getParameterName();
        String[] parameterTypeArray = null;
        Object[] parameterValueArray = null;
        if(parameterType!=null && !"".equals(parameterType)){
            parameterTypeArray = parameterType.split(",");
            parameterValueArray = CommonUtil.getParams(parameterName, params, parameterType);
        }
        return genericService.$invoke(methodName, parameterTypeArray, parameterValueArray);
    }

}
